package reflect.reference;


import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * <p>
 * 反射 案例引入
 * </P>
 *
 * @author dingwen
 * @date 2021.10.11 11:35
 */
@SuppressWarnings(value = "all")
public class Reference {
    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
        properties.load(new FileInputStream("E:\\study\\java8-study\\src\\reference\\config.Properties"));
        String classFullPath = String.valueOf(properties.get("class-full-path"));
        String methodName = String.valueOf(properties.get("method-name"));
        System.out.println("classFullPath = " + classFullPath);
        System.out.println("methodName = " + methodName);


        // 传统方式实现
//        Cat cat = new Cat();
//        cat.hello();

        // 反射实现
        // 得到Class 类型的对象
        Class<?> aClass = Class.forName(classFullPath);
        Class<?> aClass2 = Class.forName(classFullPath);
        System.out.println("aClass.hashCode() = " + aClass.hashCode());
        System.out.println("aClass2.hashCode() = " + aClass2.hashCode());

        //3. 创建对象
        // 获取对象
        Cat cat = (Cat) aClass.newInstance();
        cat.hello();


        // 5. 获取方法
        // 获取对象方法
        Method method = aClass.getMethod(methodName);
        // 关闭检查提升调用速度
        method.setAccessible(true);
        // 通过方法对象调用
        method.invoke(cat);


        // 4.获取属性
        // 获取成员变量
        // 只能获取由 public 修饰的成员变量
        Field nameField = aClass.getField("name");
        // 关闭检查提升调用速度
        nameField.setAccessible(true);
        // 设置属性
        nameField.set(cat,"dingwen");
        String name = String.valueOf(nameField.get(cat));
        System.out.println("name = " + name);


        // 5.获取构造器
        Constructor<?>[] constructors = aClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("constructor = " + constructor);
        }
        // 通过指定参数类型获取构造器
        Constructor<?> constructor = aClass.getConstructor(String.class);
        System.out.println("constructor = " + constructor);
        // 通过构造器创建对象
        Cat catNew = (Cat)constructor.newInstance("d");
        catNew.hello();


        // 常用方法

        // 1. 获取包名称
       String packageName =  aClass.getPackage().getName();
       System.out.println("packageName = " + packageName);

       // 2. 得到全类名
       String fullClassName = aClass.getName();
       System.out.println("fullClassName = " + fullClassName);

    }
}
